package org.richin.support.web.struts;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;
import org.richin.collection.util.CollectionUtils;
import org.richin.date.util.DateConverter;
import org.richin.web.struts.util.UtilDateConverter;
import org.richin.web.struts1.StrutsWebData;
import org.richin.web.struts1.annotation.Scope;
import org.springframework.util.ReflectionUtils;
import org.springside.core.web.support.StringConverter;

public class StrutsAction extends DispatchAction {
	public static final String SUCCESS = "success";
	public static final String DIRECTLY_MESSAGE_KEY = "message";
	protected static final String ERROR = "error";
	protected static final String INPUT = "input";
	protected static final String LOGIN = "login";
	protected static final String LIST = "list";
	protected static final String EDIT = "edit";
	protected static final String VIEW = "view";
	/*** 存放页面数据的KEY*/
	public static final String STRUTS_FORMDATA_KEY = "strutsWebForm";
	public StrutsAction() {
		registConverter();
	}

	public static void registConverter() {
		ConvertUtils.register(new StringConverter(), String.class);
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
		ConvertUtils.register(new LongConverter(null), Long.class);
		ConvertUtils.register(new FloatConverter(null), Float.class);
		ConvertUtils.register(new DoubleConverter(null), Double.class);
		ConvertUtils.register(new UtilDateConverter(), Date.class);
	
	}

	protected void bindEntity(ActionForm form, Object object) {
		if (form != null)
			try {
				BeanUtils.copyProperties(object, form);
			} catch (Exception e) {
				ReflectionUtils.handleReflectionException(e);
			}
	}

	protected void bindForm(ActionForm form, Object object) {
		if (object != null)
			try {
				BeanUtils.copyProperties(form, object);
			} catch (Exception e) {
				ReflectionUtils.handleReflectionException(e);
			}
	}

	@Override
	protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response, String name) throws Exception {
		//将请求的基本信息存储到当前线程中以便以后使用
		StrutsWebData webData = StrutsWebData.getStrutsWebData();
		webData.setRequest(request);
		webData.setResponse(response);
		webData.setActionForm(form);
		return super.dispatchMethod(mapping, form, request, response, name);
	}

	protected void saveMessage(HttpServletRequest request, String key, String... values) {
		ActionMessages msgs = new ActionMessages();
		msgs.add("org.apache.struts.action.GLOBAL_MESSAGE", new ActionMessage(key, values));
		saveMessages(request.getSession(), msgs);
	}

	/**添加操作的Action函数, 默认什么也不做,跳转到INPUT*/
	public ActionForward input(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) {
		return mapping.findForward(INPUT);
	}
	/**
	 * 显示Welcome页的Action函数. 默认跳转到{@link #list(ActionMapping,ActionForm,HttpServletRequest,HttpServletResponse) }
	 */
	public ActionForward index(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response)throws Exception  {
		return mapping.findForward(SUCCESS);
	}
	protected void saveDirectlyMessage(HttpServletRequest request, String message) {
		ActionMessages msgs = new ActionMessages();
		msgs.add("org.apache.struts.action.GLOBAL_MESSAGE", new ActionMessage("message", message));
		saveMessages(request.getSession(), msgs);
	}
	/**
	 * url参数未定义method时的默认Action函数. 默认为index Action.
	 */
	@Override
	public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response)throws Exception  {
		return index(mapping, form, request, response);
	}
	protected void saveError(HttpServletRequest request, String key, String... values) {
		ActionMessages errors = new ActionMessages();
		errors.add("org.apache.struts.action.GLOBAL_MESSAGE", new ActionMessage(key, values));

		saveErrors(request.getSession(), errors);
	}

	protected void saveDirectlyError(HttpServletRequest request, String message) {
		ActionMessages errors = new ActionMessages();
		errors.add("org.apache.struts.action.GLOBAL_MESSAGE", new ActionMessage("message", message));
		saveErrors(request.getSession(), errors);
	}

	protected void render(HttpServletResponse response, String text, String contentType) {
		try {
			response.setContentType(contentType);
			response.getWriter().write(text);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	protected void renderText(HttpServletResponse response, String text) {
		render(response, text, "text/plain;charset=UTF-8");
	}

	protected void renderHtml(HttpServletResponse response, String text) {
		render(response, text, "text/html;charset=UTF-8");
	}

	protected void renderXML(HttpServletResponse response, String text) {
		render(response, text, "text/xml;charset=UTF-8");
	}

	/**
	 * Retrieve a session object based on the request and the attribute name
	 */
	protected Object getSessionObject(HttpServletRequest request, String attrName) {
		Object sessionObj = null;
		HttpSession session = request.getSession(false);
		if (session != null) {
			sessionObj = session.getAttribute(attrName);
		}
		return sessionObj;
	}

	protected String getStringAttribute(String name) {
		Object object = getRequest().getAttribute(name);
		return (String) object;
	}

	public String getParameter(String name) {
		return getRequest().getParameter(name);
	}

	/**
	 * Set a session object.
	 */
	protected void setSessionObject(HttpServletRequest request, String attrName, Object object) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			session.setAttribute(attrName, object);
		}
	}
	protected  HttpSession getSession() {
		return getRequest().getSession();
	}

	protected  HttpSession getSession(boolean create) {
		return getRequest().getSession(create);
	}

	/**
	 * 用javascript弹出提示信息
	 *
	 * @param msg
	 *            显示的信息
	 * @return String
	 * @throws IOException
	 * @author hezhenbo
	 */
	protected String jsAlert(String msg) {
		try {
			getResponse().setContentType("text/html;charset=utf-8");
			PrintWriter out = getResponse().getWriter();
			out.print("<script language='javascript'>alert('" + msg + "');</script>");
			out.close();
			return null;
		} catch (Exception e) {
			log.error("jsAlert(" + msg + ") error", e);
			return null;
		}
	}

	/**
	 * 用javascript弹出提示信息并关闭窗口
	 *
	 * @param msg
	 *            显示的信息
	 * @return String
	 * @throws IOException
	 * @author hezhenbo
	 */
	protected String jsAlertAndClose(String msg) {
		try {
			getResponse().setContentType("text/html;charset=utf-8");
			PrintWriter out = getResponse().getWriter();
			out.print("<script language='javascript'>alert('" + msg + "');window.close();</script>");
			out.close();
			return null;
		} catch (Exception e) {
			log.error("jsAlertAndClose(" + msg + ") error", e);
			return null;
		}
	}

	protected void saveErrors(HttpSession session, ActionMessages errors) {
		if (errors == null || errors.isEmpty()) {
			session.removeAttribute("org.apache.struts.action.ERROR");
			return;
		} else {
			session.setAttribute("org.apache.struts.action.ERROR", errors);
			return;
		}
	}
	/**
	 * @return HttpServletRequest
	 */
	protected HttpServletRequest getRequest() {
		return StrutsWebData.getStrutsWebData().getRequest();
	}

	/**
	 * @return HttpServletResponse
	 */
	protected HttpServletResponse getResponse() {
		return StrutsWebData.getStrutsWebData().getResponse();
	}

	/**
	 * 向Request或Session或ApplicationContext中放置Attribute
	 *
	 * @param key
	 * @param value
	 */
	protected void setAttribute(String key, Object value, Scope scope) {
		if (scope == null) scope = Scope.REQUEST;
		switch (scope) {
		case SESSION:
			getRequest().getSession().setAttribute(key, value);
			break;
		case APPLICATION:
			getRequest().getSession().getServletContext().setAttribute(key,
					value);
			break;
		default:
			getRequest().setAttribute(key, value);
		}
	}

	/**
	 * 向Request中放置Attribute
	 *
	 * @param key
	 * @param value
	 */
	protected void setAttribute(String key, Object value) {
		setAttribute(key, value, null);
	}

	/**
	 * 从Request,Session,ApplicationContext中获得一个Attribute
	 * 该方法将按照Request, Session, ApplicationContext的顺序搜索指定的Attribute
	 * @param key
	 * @return Attribut的值
	 */
	protected Object getAttribute(String key) {
		Object value = getAttribute(key, Scope.REQUEST);
		if (value == null) {
			value = getAttribute(key, Scope.SESSION);
			if (value == null) {
				value = getAttribute(key, Scope.APPLICATION);
			}
		}
		return value;
	}

	/**
	 * 从Request或Session或ApplicationContext中获得一个Attribute
	 *
	 * @param key
	 * @return Attribut的值
	 */
	protected Object getAttribute(String key, Scope scope) {
		if (scope == null) return getAttribute(key);
		switch (scope) {
		case SESSION:
			return getRequest().getSession().getAttribute(key);
		case APPLICATION:
			return getRequest().getSession().getServletContext().getAttribute(key);
		default:
			return getRequest().getAttribute(key);
		}
	}

	/**
	 * 从Request, Session和Application中删除一个属性
	 * @param key
	 * @param scope
	 */
	protected void removeAttribute(String key, Scope scope) {
		if (scope == null) scope = Scope.REQUEST;
		switch (scope) {
		case SESSION:
			getRequest().getSession().removeAttribute(key);
			break;
		case APPLICATION:
			getRequest().getSession().getServletContext().removeAttribute(key);
			break;
		default:
			getRequest().removeAttribute(key);
		}
	}

	/**
	 * 从Request中删除一个属性
	 * @param key
	 */
	protected void removeAttribute(String key) {
		removeAttribute(key, Scope.REQUEST);
	}
}
